#ifndef INETIPV4_H
#define INETIPV4_H


#include <netinet/ip.h>
#include "InterfacePackOperation.h"


namespace Pacap {



class InetIpv4 :public InterfacePackOperation
{
public:
    InetIpv4()=default;
    virtual ~InetIpv4()=default;




    // InterfacePackOperation interface
public:
    virtual PackType pack() override;
    virtual void unpack(PackType hexData) override;



    unsigned int getIpHl() const;
    void setIpHl(unsigned int value);

    unsigned int getIpV() const;
    void setIpV(unsigned int value);

    u_int8_t getIpTos() const;
    void setIpTos(const u_int8_t &value);

    u_short getIpLen() const;
    void setIpLen(const u_short &value);

    u_short getIpId() const;
    void setIpId(const u_short &value);

    u_short getIpOff() const;
    void setIpOff(const u_short &value);

    u_int8_t getIpP() const;
    void setIpP(const u_int8_t &value);

    u_short getIpSum() const;
    void setIpSum(const u_short &value);

    in_addr getIpSrc() const;
    void setIpSrc(const in_addr &value);

    in_addr getIpDst() const;
    void setIpDst(const in_addr &value);

    PackType getData() const;
    void setData(const PackType &value);

    static size_t getLENGTH();
private:
#pragma pack(push)
#pragma pack(1)
    struct head{
#if __BYTE_ORDER == __LITTLE_ENDIAN
        unsigned int ipHl:4;		/* header length */
        unsigned int ipV:4;		/* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
        unsigned int ip_v:4;		/* version */
        unsigned int ip_hl:4;		/* header length */
#endif
        u_int8_t ipTos;			/* type of service */
        u_short ipLen;			/* total length */
        u_short ipId;			/* identification */
        u_short ipOff;			/* fragment offset field */
#define	IP_RF 0x8000			/* reserved fragment flag */
#define	IP_DF 0x4000			/* dont fragment flag */
#define	IP_MF 0x2000			/* more fragments flag */
#define	IP_OFFMASK 0x1fff		/* mask for fragmenting bits */
        u_int8_t ipTtl;			/* time to live */
        u_int8_t ipP;			/* protocol */
        u_short ipSum;			/* checksum */
        struct in_addr ipSrc;
        struct in_addr ipDst;	/* source and dest address */
    } head;
#pragma pack(pop)

    PackType data;
};


}

#endif // INETIPV4_H
